# emotion_utils.py - 重构版情绪分析工具
import os

import cv2
import requests
import time
import threading
from datetime import datetime
import logging

logger = logging.getLogger(__name__)

# Face++ API配置
API_KEY = 'Dd5VZRoeYdAorlSEN3uo8DWVgMBlIkom'
API_SECRET = '868huzzuO-VkgE0bdp7w5_UTJ4IxadEs'
FACEPP_URL = 'https://api-cn.faceplusplus.com/facepp/v3/detect'

# 情绪映射
EMOTION_MAP = {
    'anger': '愤怒',
    'disgust': '厌恶',
    'fear': '恐惧',
    'happiness': '高兴',
    'neutral': '平静',
    'sadness': '伤心',
    'surprise': '惊讶'
}

# 全局变量
emotion_data = []  # 存储情绪检测结果
recording_active = False
recording_thread = None
data_lock = threading.Lock()


def analyze_emotion_from_camera():
    """从摄像头分析情绪"""
    try:
        # 打开摄像头
        cap = cv2.VideoCapture(0)
        if not cap.isOpened():
            logger.error("无法打开摄像头")
            return None

        # 设置摄像头参数
        cap.set(cv2.CAP_PROP_FRAME_WIDTH, 640)
        cap.set(cv2.CAP_PROP_FRAME_HEIGHT, 480)

        ret, frame = cap.read()
        cap.release()

        if not ret:
            logger.error("无法读取摄像头画面")
            return None

        # 检查图像是否为空
        if frame is None or frame.size == 0:
            logger.error("摄像头返回空图像")
            return None

        # 保存临时图片
        temp_path = f"temp/emotion_temp_{int(time.time())}.jpg"
        os.makedirs('temp', exist_ok=True)

        success = cv2.imwrite(temp_path, frame)
        if not success:
            logger.error("保存临时图像失败")
            return None

        # 检查文件大小
        if os.path.getsize(temp_path) < 1000:  # 小于1KB可能是无效图像
            logger.warning("图像文件过小，可能无效")
            try:
                os.remove(temp_path)
            except:
                pass
            return None

        # 分析情绪
        emotion_result = analyze_emotion_from_file(temp_path)

        # 清理临时文件
        try:
            os.remove(temp_path)
        except:
            pass

        return emotion_result

    except Exception as e:
        logger.error(f"摄像头情绪分析失败: {e}")
        return None


def analyze_emotion_from_file(image_path):
    """从文件分析情绪"""
    try:
        with open(image_path, 'rb') as image_file:
            files = {'image_file': image_file}
            data = {
                'api_key': API_KEY,
                'api_secret': API_SECRET,
                'return_attributes': 'emotion'
            }

            response = requests.post(FACEPP_URL, data=data, files=files, timeout=10)
            response.raise_for_status()
            result = response.json()

            if 'faces' in result and result['faces']:
                emotion_data = result['faces'][0]['attributes']['emotion']

                # 找到主导情绪
                top_emotion = max(emotion_data, key=emotion_data.get)
                top_value = emotion_data[top_emotion]

                return {
                    'timestamp': datetime.now().isoformat(),
                    'emotions': emotion_data,
                    'dominant_emotion': EMOTION_MAP.get(top_emotion, top_emotion),
                    'confidence': top_value
                }
            else:
                logger.warning("未检测到人脸")
                return None

    except Exception as e:
        logger.error(f"情绪分析API调用失败: {e}")
        return None


def emotion_recording_loop():
    """情绪录制循环"""
    global recording_active, emotion_data

    logger.info("开始情绪监测循环")

    consecutive_failures = 0
    max_failures = 5

    while recording_active:
        try:
            # 分析当前情绪
            emotion_result = analyze_emotion_from_camera()

            if emotion_result:
                consecutive_failures = 0  # 重置失败计数
                with data_lock:
                    emotion_data.append(emotion_result)
                    logger.info(
                        f"检测到情绪: {emotion_result['dominant_emotion']} ({emotion_result['confidence']:.1f}%)")
            else:
                consecutive_failures += 1

                # 连续失败时添加默认情绪数据，避免评分异常
                if consecutive_failures >= max_failures:
                    logger.warning(f"连续{max_failures}次未检测到人脸，使用默认情绪数据")
                    default_emotion = {
                        'timestamp': datetime.now().isoformat(),
                        'emotions': {'neutral': 70, 'happiness': 20, 'sadness': 10},
                        'dominant_emotion': '平静',
                        'confidence': 70.0
                    }
                    with data_lock:
                        emotion_data.append(default_emotion)
                    consecutive_failures = 0  # 重置计数
                elif consecutive_failures == 1:
                    logger.warning("未检测到人脸，请确保摄像头正常且面向摄像头")

            # 等待1秒
            time.sleep(1)

        except Exception as e:
            logger.error(f"情绪监测循环异常: {e}")
            time.sleep(1)



logger.info("情绪监测循环结束")


def start_emotion_recording():
    """开始情绪录制"""
    global recording_active, recording_thread, emotion_data

    if recording_active:
        logger.warning("情绪录制已在进行中")
        return

    # 清空旧数据
    with data_lock:
        emotion_data.clear()

    recording_active = True
    recording_thread = threading.Thread(target=emotion_recording_loop, daemon=True)
    recording_thread.start()

    logger.info("情绪录制已开始")


def stop_emotion_recording():
    """停止情绪录制"""
    global recording_active

    recording_active = False

    if recording_thread and recording_thread.is_alive():
        recording_thread.join(timeout=2)

    logger.info("情绪录制已停止")


def get_emotion_stats():
    """获取情绪统计信息 - 只计算有效识别结果"""
    with data_lock:
        if not emotion_data:
            return {
                'total_samples': 0,
                'valid_samples': 0,
                'emotions': {},
                'calm_percentage': 0,
                'dominant_emotion': '未知',
                'recognition_rate': 0
            }

        # 🔥 修复：只统计有效的情绪识别结果
        valid_emotions = [record for record in emotion_data if record and 'dominant_emotion' in record]

        if not valid_emotions:
            return {
                'total_samples': len(emotion_data),
                'valid_samples': 0,
                'emotions': {},
                'calm_percentage': 0,
                'dominant_emotion': '未知',
                'recognition_rate': 0
            }

        # 统计各种情绪出现次数（只计算有效识别）
        emotion_counts = {}
        for record in valid_emotions:
            emotion = record['dominant_emotion']
            emotion_counts[emotion] = emotion_counts.get(emotion, 0) + 1

        valid_samples = len(valid_emotions)
        total_samples = len(emotion_data)

        # 计算平静情绪百分比（基于有效识别）
        calm_count = emotion_counts.get('平静', 0)
        calm_percentage = (calm_count / valid_samples * 100) if valid_samples > 0 else 0

        # 找到最常出现的情绪
        dominant_emotion = max(emotion_counts, key=emotion_counts.get) if emotion_counts else '未知'

        # 识别成功率
        recognition_rate = (valid_samples / total_samples * 100) if total_samples > 0 else 0

        stats = {
            'total_samples': total_samples,
            'valid_samples': valid_samples,
            'emotions': emotion_counts,
            'calm_percentage': round(calm_percentage, 1),
            'dominant_emotion': dominant_emotion,
            'recognition_rate': round(recognition_rate, 1),
            'recording_duration': total_samples,  # 大约等于秒数
        }

        logger.info(
            f"情绪统计 - 总样本:{total_samples}, 有效:{valid_samples}, 识别率:{recognition_rate:.1f}%, 平静比例:{calm_percentage:.1f}%, 主导情绪:{dominant_emotion}")
        return stats


def clear_emotion_data():
    """清空情绪数据"""
    global emotion_data

    with data_lock:
        emotion_data.clear()

    logger.info("情绪数据已清空")


def get_current_emotion_data():
    """获取当前所有情绪数据"""
    with data_lock:
        return emotion_data.copy()


def export_emotion_report(filename="emotion_report.json"):
    """导出情绪报告"""
    try:
        import json

        stats = get_emotion_stats()
        raw_data = get_current_emotion_data()

        report = {
            'export_time': datetime.now().isoformat(),
            'statistics': stats,
            'raw_data': raw_data
        }

        with open(filename, 'w', encoding='utf-8') as f:
            json.dump(report, f, ensure_ascii=False, indent=2)

        logger.info(f"情绪报告已导出: {filename}")
        return filename

    except Exception as e:
        logger.error(f"导出情绪报告失败: {e}")
        return None


# 添加兼容性别名
def get_current_emotion_stats():
    """获取当前轮次的情绪统计（兼容性函数）"""
    return get_emotion_stats()


def export_emotion_to_excel(filename="emotion_report.xlsx"):
    """导出情绪数据到Excel（兼容性函数）"""
    try:
        import pandas as pd

        stats = get_emotion_stats()
        raw_data = get_current_emotion_data()

        # 创建数据框
        if raw_data:
            df_data = []
            for i, record in enumerate(raw_data, 1):
                df_data.append({
                    '序号': i,
                    '时间': record['timestamp'],
                    '主导情绪': record['dominant_emotion'],
                    '置信度': record['confidence']
                })
            df = pd.DataFrame(df_data)
        else:
            df = pd.DataFrame(columns=['序号', '时间', '主导情绪', '置信度'])

        # 导出Excel
        df.to_excel(filename, index=False)
        logger.info(f"情绪报告已导出: {filename}")
        return filename

    except Exception as e:
        logger.error(f"导出Excel失败: {e}")
        return export_emotion_report(filename.replace('.xlsx', '.json'))


# 测试函数
def test_emotion_api():
    """测试情绪分析API"""
    try:
        import numpy as np

        # 创建测试图片
        test_image = np.zeros((100, 100, 3), dtype=np.uint8)
        test_path = "temp/test_emotion.jpg"

        import os
        os.makedirs('temp', exist_ok=True)
        cv2.imwrite(test_path, test_image)

        # 测试API
        result = analyze_emotion_from_file(test_path)

        # 清理
        try:
            os.remove(test_path)
        except:
            pass

        if result is not None:
            logger.info("情绪API测试成功")
            return True
        else:
            logger.warning("情绪API测试未检测到人脸（正常）")
            return True

    except Exception as e:
        logger.error(f"情绪API测试失败: {e}")
        return False


if __name__ == "__main__":
    # 运行测试
    print("测试情绪分析API...")
    success = test_emotion_api()
    print(f"测试结果: {'成功' if success else '失败'}")